package io.bdmc.modules.bss.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.bdmc.common.annotation.SysLogger1;
import io.bdmc.common.utils.*;
import io.bdmc.common.utils.Constant.ModifyName;
import io.bdmc.core.snmp.cache.ConcurrentHashMapCacheUtils;
import io.bdmc.modules.bss.entity.DeviceAlarm;
import io.bdmc.modules.bss.entity.DeviceAlarmRealtime;
import io.bdmc.modules.bss.entity.DeviceDevice;
import io.bdmc.modules.bss.model.DeviceAlarmRealtimeParam;
import io.bdmc.modules.bss.service.IDeviceAlarmRealtimeService;
import io.bdmc.modules.bss.service.IDeviceDeviceService;
import io.bdmc.modules.sys.controller.AbstractController;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 设备报警历史记录 前端控制器
 * </p>
 *
 * @author 黄露
 * @since 2020-09-15
 */

// "设备报警历史记录", description = "设备报警历史记录")
@RestController
@RequestMapping("/bss/alarm/realtime")
public class DeviceAlarmRealtimeController extends AbstractController {

	@Autowired
	IDeviceAlarmRealtimeService _alarmRealtimeSvs;

	@Autowired
	IDeviceDeviceService deviceService;

	@GetMapping("/list")
	// "查询设备报警实时信息", notes = "查询设备报警实时信息")
	// @RequiresPermissions("bss:alarm:list")
	public R list(DeviceAlarmRealtimeParam params) {
		MyPage<DeviceAlarmRealtime> myPage = new MyPage<>(params.getCurrent(), params.getSize());
		MyPage<DeviceAlarmRealtime> map = _alarmRealtimeSvs.mySelectPage(myPage, params);
		return R.ok().putData(MyMap.ok(map.getRecords(), map.getTotal()));

	}

	@GetMapping("/all")
	// "查询设备报警实时信息", notes = "查询设备报警实时信息")
	// @RequiresPermissions("bss:alarm:list")
	public R all(DeviceAlarmRealtimeParam params) {
		params.setDeptId(getDeptId());
		return R.ok().putData(_alarmRealtimeSvs.selectAllLastAlarm(params));

	}

	@SysLogger1(value = "结束告警", entityType = DeviceAlarm.class, operationType = ModifyName.None)
	@PostMapping("/process")
	// "确认设备报警信息", notes = "确认设备报警信息")
	public R process(@RequestBody DeviceAlarm alarm) {
		int alarmId = alarm.getAlarmId();
		alarm.setAlarmId(0);
		LocalDateTime now = LocalDateTime.now();
		alarm.setEndTime(now);
		if (!alarm.getProcessed()) {
			alarm.setProcessed(true);
			alarm.setProcessBy(getUser().getUsername());
			alarm.setProcessTime(now);
		}

		alarm.setEndAlarm(true);
		alarm.insert();
		_alarmRealtimeSvs.removeById(alarmId);
		if ((Constant.ALARM_Distance).equals(alarm.getAlarmTypeCode())) {
			DeviceDevice dd = deviceService.getById(alarm.getDeviceId());
			String str = Constant.routeOTDRAlarmTimes + dd.getDeviceSn();
			ConcurrentHashMapCacheUtils.deleteCache(str);
		}
		return R.ok();
	}

	@SysLogger1(value = "结束所有告警", entityType = DeviceAlarm.class, operationType = ModifyName.None)
	@PostMapping("/processAll")
	// "确认设备报警信息", notes = "确认设备报警信息")
	public R processAll() {
		List<DeviceAlarmRealtime> list = _alarmRealtimeSvs.list();
		LocalDateTime now = LocalDateTime.now();
		for (DeviceAlarmRealtime realtime : list) {
			String s = JSON.toJSONString(realtime);
			DeviceAlarm alarm = JSONObject.parseObject(s, DeviceAlarm.class);
			// DeviceAlarm alarm = BeanUtils.convert(realtime, DeviceAlarm.class);
			alarm.setAlarmId(0);
			alarm.setEndTime(now);
			if (!alarm.getProcessed()) {
				alarm.setProcessed(true);
				alarm.setProcessBy(getUser().getUsername());
				alarm.setProcessTime(now);
			}
			alarm.setEndAlarm(true);
			alarm.insert();
			if ((Constant.ALARM_Distance).equals(alarm.getAlarmTypeCode())) {
				DeviceDevice dd = deviceService.getById(alarm.getDeviceId());
				if (dd != null) {
					String str = Constant.routeOTDRAlarmTimes + dd.getDeviceSn();
					ConcurrentHashMapCacheUtils.deleteCache(str);
				}
			}
		}
		_alarmRealtimeSvs.remove(new LambdaQueryWrapper<DeviceAlarmRealtime>().gt(DeviceAlarmRealtime::getAlarmId, 0));
		return R.ok();
	}

	@SysLogger1(value = "确认报警但不结束", entityType = DeviceAlarm.class, operationType = ModifyName.UPDATE)
	@PostMapping("/confirm")
	// "确认设备报警信息", notes = "确认设备报警信息")
	public R confirmed(@RequestBody DeviceAlarmRealtime realtime) {
		realtime.setProcessed(true);
		realtime.setProcessBy(getUser().getUsername());
		realtime.setProcessTime(LocalDateTime.now());
		realtime.setEndAlarm(true);
		realtime.updateById();
		return R.ok();
	}

	@GetMapping("/count")
	// "报警数量", notes = "报警数量")
	public R alarmCount() {
		long count = _alarmRealtimeSvs.count();
		return R.ok().putData(count);
	}

	@RequestMapping(value = "export")
	public R export(DeviceAlarmRealtimeParam params) throws IOException {
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("设备实时告警记录");
		MyPage<DeviceAlarmRealtime> myPage = new MyPage<DeviceAlarmRealtime>(1, 30000);
		MyPage<DeviceAlarmRealtime> map = _alarmRealtimeSvs.mySelectPage(myPage, params);
		List<DeviceAlarmRealtime> list = map.getRecords();
		String dateString = DateUtils.formatLocalDateTime(LocalDateTime.now(), DateUtils.Pay_DATE_TIME_PATTERN);
		String fileName = "设备实时告警记录" + dateString + ".xls";// 设置要导出的文件的名字

		Map<String, CellStyle> styles = ExcelImport.createStyles(workbook);

		// 新增数据行，并且设置单元格数据
		int rowNum = 0;
		String[] headers = { "序号", "设备名称", "设备型号", "端口", "告警名称", "告警编码", "告警级别", "告警信息", "确认状态", "确认用户", "开始时间",
				"最后告警时间", "可能原因", "处理方法", };

		rowNum = ExcelImport.initialize(rowNum, "设备实时告警记录", headers, workbook, sheet, styles);
		// 在表中存放查询到的数据放入对应的列
		int dataIndex = 1;
		for (DeviceAlarmRealtime dd : list) {
			HSSFRow row1 = sheet.createRow(rowNum++);
			row1.createCell(0).setCellValue(dataIndex);
			row1.createCell(1).setCellValue(dd.getDeviceName());
			row1.createCell(2).setCellValue(ExcelImport.convertNullString(dd.getDeviceModel()));
			row1.createCell(3).setCellValue(ExcelImport.convertNullString(dd.getChannel()));
			row1.createCell(4).setCellValue(ExcelImport.convertNullString(dd.getAlarmTypeName()));
			row1.createCell(5).setCellValue(ExcelImport.convertNullString(dd.getAlarmTypeCode()));
			row1.createCell(6).setCellValue(ExcelImport.convertNullString(getAlarmLevelString(dd.getAlarmLevel())));
			row1.createCell(7).setCellValue(ExcelImport.convertNullString(dd.getAlarmMsg()));
			row1.createCell(8).setCellValue(ExcelImport.convertNullString(dd.getProcessed() ? "已确认" : "未确认"));
			row1.createCell(9).setCellValue(ExcelImport.convertNullString(dd.getProcessBy()));
			row1.createCell(10).setCellValue(
					ExcelImport.convertNullString(DateUtils.formatLocalDateTimeDefault(dd.getStartTime())));
			row1.createCell(11).setCellValue(
					ExcelImport.convertNullString(DateUtils.formatLocalDateTimeDefault(dd.getLastTime())));
			row1.createCell(12).setCellValue(ExcelImport.convertNullString(dd.getPossibleCause()));
			row1.createCell(13).setCellValue(ExcelImport.convertNullString(dd.getProcessMethod()));
			dataIndex++;
		}
		try {
			File path = new File(Constant.EXPORTPATH);
			if (!path.exists()) {
				path.mkdir();
			}
			File f = new File(path.getAbsolutePath() + "/excel/", fileName);
			if (!f.getParentFile().exists()) {
				f.getParentFile().mkdir();
			}
			FileOutputStream fileOutputStream = new FileOutputStream(f);// 指定路径与名字和格式
			workbook.write(fileOutputStream);// 将数据写出去
			fileOutputStream.close();// 关闭输出流
			return R.ok().putData("/excel/" + fileName);
		} catch (Exception e) {
			e.printStackTrace();
			return R.error(-1, e.getMessage());
		}
	}

	private String getAlarmLevelString(String alarmLevel) {
		String str = "";
		switch (alarmLevel) {
			case "A":
				str = "紧急告警";
				break;
			case "B":
				str = "主要告警";
				break;
			case "C":
				str = "次要告警";
				break;
			case "D":
				str = "提示告警";
				break;
			default:
				break;
		}
		return str;
	}
}
